Olaf eliminates a zillion hardcoded staticly sized buffers and commonizes
authorrobertl <robertl>
Thu, 13 Jul 2006 05:33:37 +0000 (05:33 +0000)
committerrobertl <robertl>
Thu, 13 Jul 2006 05:33:37 +0000 (05:33 +0000)
our ASCII text reader into the new 'textfile' scheme.

25 files changed:
Makefile.in
arcdist.c
compegps.c
configure.in
cst.c
csv_util.c
defs.h
garmin_txt.c
google.c
gpsutil.c
hsa_ndv.c
igc.c
inifile.c
netstumbler.c
nmea.c
nmn4.c
ozi.c
pcx.c
polygon.c
stmwpp.c
textfile.c [new file with mode: 0644]
tiger.c
tmpro.c
unicsv.c
xcsv.c

index 726c881ebcb0c3c275f2eca40d2ab039337274d0..b2489749e0abcc82eb1a1ebde43596b7b19c40ce 100644 (file)
@@ -73,7 +73,7 @@ SHAPE=shapelib/shpopen.o shapelib/dbfopen.o
 LIBOBJS = queue.o route.o waypt.o filter_vecs.o util.o vecs.o mkshort.o \
           csv_util.o strptime.o grtcirc.o vmem.o util_crc.o xmlgeneric.o \
           uuid.o formspec.o xmltag.o cet.o cet_util.o fatal.o rgbcolors.o \
-         inifile.o garmin_fs.o gbsleep.o units.o @GBSER@ \
+         inifile.o garmin_fs.o gbsleep.o units.o textfile.o @GBSER@ \
        $(COLDSYNC) $(GARMIN) $(JEEPS) $(SHAPE) $(FMTS) $(FILTERS)
 OBJS = main.o globals.o $(LIBOBJS)
 
index e0379f42e2f53443bc7a0a826f7c69181b058e59..c173c7ca5d144e6bf0d5a16ade9c315a6201360d 100644 (file)
--- a/arcdist.c
+++ b/arcdist.c
@@ -59,17 +59,16 @@ arcdist_process(void)
        extra_data *ed;
         double lat1, lon1, lat2, lon2;
        int fileline = 0;
+       char *line;
+       textfile_t *tin;
 
-       FILE *arcfile = xfopen( arcfileopt, "r", MYNAME );
+       tin = textfile_open_read(arcfileopt, MYNAME );
        
         lat1 = lon1 = lat2 = lon2 = BADVAL;
-       while ( !feof(arcfile)) {
-           char line[200];
+       while ((line = textfile_read(tin))) {
            char *pound = NULL;
            int argsfound = 0;
            
-           fgets( line, sizeof(line), arcfile );
-          
            fileline++;
            
            pound = strchr( line, '#' );
@@ -124,8 +123,7 @@ arcdist_process(void)
            lon1 = lon2;
        }
            
-       fclose(arcfile);
-
+       textfile_done(tin);
 
        QUEUE_FOR_EACH(&waypt_head, elem, tmp) {
                waypoint *wp = (waypoint *) elem;
index 404230a66b595f0a2c1b83201d4c67c7a5cdcccd..1e41df8ccd86784b4632c773f0dc6c9c58f0ac9d 100644 (file)
@@ -318,7 +318,7 @@ static void
 compegps_rd_init(const char *fname)
 {
        fin_name = (char *)fname;
-       fin = xfopen(fname, "r", MYNAME);
+       fin = xfopen(fname, "rb", MYNAME);
 }
 
 static void
@@ -330,13 +330,15 @@ compegps_rd_deinit(void)
 static void
 compegps_data_read(void)
 {
-       char buff[1024];
+       textfile_t *tin;
+       char *buff;
        int line = 0;
        waypoint *wpt = NULL;
        route_head *route = NULL;
        route_head *track = NULL;
        
-       while (NULL != fgets(buff, sizeof(buff), fin))
+       tin = textfile_init(fin);
+       while ((buff = textfile_read(tin)))
        {
                char *cin = buff;
                char *ctail, *cx;
@@ -405,7 +407,8 @@ compegps_data_read(void)
                                        parse_track_info(ctail, track);
                                break;
                }
-       }         
+       }
+       textfile_done(tin);
 }
 
 /* ----------------------------------------------------------- */
index 6bfd7f0e9807f5012d81a28ec5b89b76a37215da..65adeb687a9c3eedde9f9bf69dc8f101f6175525 100644 (file)
@@ -67,7 +67,7 @@ AC_ARG_ENABLE(csv,
        AC_MSG_RESULT(no)
     fi
 
-AC_MSG_CHECKING(whether to support csv formats)
+AC_MSG_CHECKING(whether to support filters)
 AC_ARG_ENABLE(filters,
   [  --enable-filters=[(yes)|no]],
   [ enable_filters="$enableval"],[enable_filters="yes"])
diff --git a/cst.c b/cst.c
index d2b58863de54eb2779d7e91ee0e8eaed7633635a..8528d3b5ad14a64e8da6832f597fe717b4914def 100644 (file)
--- a/cst.c
+++ b/cst.c
@@ -140,7 +140,7 @@ static void
 cst_rd_init(const char *fname)
 {
        fin_name = xstrdup(fname);
-       fin = xfopen(fname, "r", MYNAME);
+       fin = xfopen(fname, "rb", MYNAME);
        
        temp_route = NULL;
 }
@@ -157,7 +157,7 @@ cst_rd_deinit(void)
 static void
 cst_data_read(void)
 {
-       char buff[1024];
+       char *buff;
        int line = 0;
        int data_lines = -1;
        int line_of_count = -1;
@@ -167,9 +167,11 @@ cst_data_read(void)
        int cst_points = -1;
        route_head *track = NULL;
        waypoint *wpt = NULL;
+       textfile_t *tin;
        
+       tin = textfile_init(fin);
        
-       while (NULL != fgets(buff, sizeof(buff), fin))
+       while ((buff = textfile_read(tin)))
        {
                char *cin = buff;
                
@@ -214,14 +216,15 @@ cst_data_read(void)
                                                        wpt->url = cst_make_url(cin);
                                        }
                                        
-                                       while (NULL != fgets(buff, sizeof(buff), fin))
+                                       while ((buff = textfile_read(tin)))
                                        {
                                                line++;
                                                cin = lrtrim(buff);
                                                
                                                if (strcmp(cin + 2, "note") == 0)
                                                {
-                                                       fgets(buff, sizeof(buff), fin);
+                                                       buff = textfile_read(tin);
+                                                       if (buff == NULL) buff = "";
                                                        line++;
                                                        cin = lrtrim(buff);
                                                        if (*cin != '\0')
@@ -315,6 +318,8 @@ cst_data_read(void)
        
        if ((cst_points >= 0) && (data_lines != cst_points))
                warning(MYNAME ": Loaded %d point(s), but line %d says %d!\n", data_lines, line_of_count, cst_points);
+       
+       textfile_done(tin);
 }
 
 #if 0
index c485a3f8a1c970ff97a6d1e9ded8b1dd8b0a37df..fdb14b7e94e1e04163d1bb289f77d4272dfe17bf 100644 (file)
@@ -994,20 +994,20 @@ xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp)
 void
 xcsv_data_read(void)
 {
-    char buff[8192];
+    char *buff;
     char *s;
     waypoint *wpt_tmp;
     int linecount = 0;
     queue *elem, *tmp;
     field_map_t *fmp;
     ogue_t *ogp;
+    textfile_t *tin;
+    
+    tin = textfile_init(xcsv_file.xcsvfp);
 
-    do {
+    while ((buff = textfile_read(tin))) {
         linecount++;
-        memset(buff, '\0', sizeof(buff));
-        fgets(buff, sizeof(buff), xcsv_file.xcsvfp);
-
-        rtrim(buff);
+        buff = lrtrim(buff);
 
         /* skip over x many lines on the top for the prologue... */
         if ((xcsv_file.prologue_lines) && ((linecount - 1) <
@@ -1060,7 +1060,8 @@ xcsv_data_read(void)
             waypt_add(wpt_tmp);
         }
 
-    } while (!feof(xcsv_file.xcsvfp));
+    }
+    textfile_done(tin);
 }
 
 static void
diff --git a/defs.h b/defs.h
index a9a6073e31a3fba871c7b2a555ed1a91b178082b..30487f504147c27df644cf2c4a584ab40c0225c8 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -796,4 +796,26 @@ int color_to_bbggrr(char *cname);
  */
 #define unknown_alt -99999999.0
 
+/*
+ * textfile: buffered OS independent (CRLF,NL,CR) text reader
+ */
+typedef struct
+{
+       FILE *file_in;
+       char buf[1024];
+       char *buf_pos;
+       char *buf_end;
+       char *line;
+       int line_size;
+       int line_no;
+       unsigned char tfclose:1;
+} textfile_t;
+
+textfile_t *textfile_init(const FILE *file_in);
+textfile_t *textfile_open_read(const char *filename, const char *module);
+void textfile_done(textfile_t *tf);
+char *textfile_read(textfile_t *tf);
+int textfile_getc(textfile_t *tf);
+
 #endif /* gpsbabel_defs_h_included */
index 9709e85b281b90db606a259e987ec80b6c0391cb..52d50efcd127c4b61d67a62026f8a1d60fca8f80 100644 (file)
@@ -1224,11 +1224,13 @@ garmin_rd_deinit(void)
 static void
 garmin_txt_read(void)
 {
-       char buff[1024];
+       char *buff;
+       textfile_t *tin;
 
        current_line = 0;
+       tin = textfile_init(fin);
 
-       while ((fgets(buff, sizeof(buff), fin))) {
+       while ((buff = textfile_read(tin))) {
                char *cin;
                
                current_line++;
@@ -1253,6 +1255,7 @@ garmin_txt_read(void)
                /* flush pending data */
                while (csv_lineparse(NULL, "\t", "", 0));
        }
+       textfile_done(tin);
 }
 
 ff_vecs_t garmin_txt_vecs = {
index 8e1872fac8eb87655ec8f16a0a18b1a72d923a50..6ff6a8f595fba0a837a2e7fe0020f5cad70e7a2e 100644 (file)
--- a/google.c
+++ b/google.c
@@ -345,7 +345,6 @@ google_read(void)
                  }
                }
                xfree( script );
-               script = NULL;
        }
 }
 #endif
@@ -355,8 +354,6 @@ google_rd_deinit(void)
 {
        xml_deinit();
        mkshort_del_handle(&desc_handle);
-       encoded_points = NULL;
-       encoded_levels = NULL;
 }
 
 ff_vecs_t google_vecs = {
index 9b108ad78d62b8d7df8df3a33dd5a55fb3ed95c0..9881b7d9bfad3bc3cd05888498fa0af60b33f52e 100644 (file)
--- a/gpsutil.c
+++ b/gpsutil.c
@@ -30,7 +30,7 @@ static short_handle mkshort_handle;
 static void
 rd_init(const char *fname)
 {
-       file_in = xfopen(fname, "r", MYNAME);
+       file_in = xfopen(fname, "rb", MYNAME);
 }
 
 static void
@@ -56,7 +56,7 @@ wr_deinit(void)
 static void
 data_read(void)
 {
-       char ibuf[100];
+       char *ibuf;
        char name[9], desc[31];
        double lat,lon;
        char latdir, londir;
@@ -65,17 +65,20 @@ data_read(void)
        char alttype;
        char icon[3] = {0};
        waypoint *wpt_tmp;
+       textfile_t *tin;
+       
+       tin = textfile_init(file_in);
        /*
         * Make sure that all waypoints in single read have same 
         * timestamp.
         */
        time_t now = current_time();
 
-
-       for(;fgets(ibuf, sizeof(ibuf), file_in);) {
+       while ((ibuf = textfile_read(tin))) {
        /*  A sharp in column zero or an blank line is a comment */
-       if (ibuf[0] == '#' || ibuf[0] == '\n') continue;
-       sscanf(ibuf, "%s %le%c %le%c %ld%c %30[^,] %c",
+               ibuf = lrtrim(ibuf);
+               if (ibuf[0] == '#' || ibuf[0] == '\n') continue;
+               sscanf(ibuf, "%s %le%c %le%c %ld%c %30[^,] %c",
                        name, &lat, &latdir, &lon, &londir,
                        &alt, &alttype, desc, icon);
                desc[0] = '\0';
@@ -102,6 +105,7 @@ data_read(void)
                wpt_tmp->icon_descr = mag_find_descr_from_token(icon);
                waypt_add(wpt_tmp);
        }
+       textfile_done(tin);
 }
 
 static void
index 18abb53ee4c817001c3bf813c6df563cdae275db..58a41e1cd96065a90f423d165cc37ebdf80e82f9 100644 (file)
--- a/hsa_ndv.c
+++ b/hsa_ndv.c
@@ -247,7 +247,7 @@ hsa_ndv_read(void)
                }
                if (!XML_Parse(psr, buf, len, feof(fd))) {
                        fatal(MYNAME ":Parse error at %d: %s\n", 
-                               XML_GetCurrentLineNumber(psr),
+                               (int) XML_GetCurrentLineNumber(psr),
                                XML_ErrorString(XML_GetErrorCode(psr)));
                }
        }
diff --git a/igc.c b/igc.c
index 0ff3e96acb8684e62ffd8f81ca3b5352a51bd13c..6930270425c8ef9218a9a7f0b7ea0b73eac49f65 100644 (file)
--- a/igc.c
+++ b/igc.c
 #include "defs.h"
 #include <errno.h>
 
-static FILE *file_in;
 static FILE *file_out;
 static char manufacturer[4];
 static const route_head *head;
 static char *timeadj = NULL;
+static textfile_t* tin;
 
 #define MYNAME "IGC"
 #define MAXRECLEN 79           // Includes null terminator and CR/LF
@@ -88,42 +88,37 @@ static unsigned char coords_match(double lat1, double lon1, double lat2, double
  * @param  rec  Caller allocated storage for the record.  At least MAXRECLEN chars must be allocated.
  * @return the record type.  rec_none on EOF, rec_bad on fgets() or parse error.
  */
-static igc_rec_type_t get_record(char *rec)
+static igc_rec_type_t get_record(char **rec)
 {
     size_t len;
+    char *c;
 
-    if (fgets(rec, MAXRECLEN, file_in) == NULL) {
-       if (feof(file_in)) {
-           return rec_none;
-       } else {
-           warning(MYNAME " fgets(): %s\n", strerror(errno));
-           return rec_bad;
-       }
-    }
-    len = strlen(rec);
-    if (len < 3 || rec[0] < 'A' || rec[0] > 'Z') {
-       warning(MYNAME " bad input record: '%s'\n", rec);
+    *rec = c = textfile_read(tin);
+    if (c == NULL) return rec_none;
+
+    len = strlen(c);
+    if (len < 3 || c[0] < 'A' || c[0] > 'Z') {
+       warning(MYNAME " bad input record: '%s'\n", c);
        return rec_bad;
     }
-    rec[len - 2] = '\0';
-    return (igc_rec_type_t) rec[0];
+    return (igc_rec_type_t) c[0];
 }
 
 static void rd_init(const char *fname)
 {
-    char ibuf[MAXRECLEN];
+    char *ibuf;
 
-    file_in = xfopen(fname, "rb", MYNAME);
+    tin = textfile_open_read(fname, MYNAME);
 
     // File must begin with a manufacturer/ID record
-    if (get_record(ibuf) != rec_manuf_id || sscanf(ibuf, "A%3[A-Z]", manufacturer) != 1) {
+    if (get_record(&ibuf) != rec_manuf_id || sscanf(ibuf, "A%3[A-Z]", manufacturer) != 1) {
        fatal(MYNAME ": %s is not an IGC file\n", fname);
     }
 }
 
 static void rd_deinit(void)
 {
-    fclose(file_in);
+    textfile_done(tin);
 }
 
 /**
@@ -240,7 +235,7 @@ static void igc_task_rec(const char *rec)
 
 static void data_read(void)
 {
-    char ibuf[MAXRECLEN];
+    char *ibuf;
     igc_rec_type_t rec_type;
     unsigned int hours, mins, secs;
     unsigned int lat_deg, lat_min, lat_frac;
@@ -266,7 +261,7 @@ static void data_read(void)
     strcpy(trk_desc, HDRMAGIC HDRDELIM);
 
     while (1) {
-       rec_type = get_record(ibuf);
+       rec_type = get_record(&ibuf);
        switch (rec_type) {
        case rec_manuf_id:
            // Manufacturer/ID record already found in rd_init().
index 8b2b26d9ff3743fbf36c524fd4ca4744b39c11c3..5dd2b025f5d74dbf51be795c7b4d13824b4e54b5 100644 (file)
--- a/inifile.c
+++ b/inifile.c
@@ -73,7 +73,7 @@ try_open_gpsbabel_inifile(const char *path)           /* can be empty or NULL */
 #endif
        }
        strcat(buff, GPSBABEL_INIFILE);
-       result = fopen(buff, "r");
+       result = fopen(buff, "rb");
        xfree(buff);
        
        return result;
@@ -87,7 +87,7 @@ open_gpsbabel_inifile(void)
        
        envstr = getenv("GPSBABELINI");
        if (envstr != NULL) {
-               res = fopen(envstr, "r");
+               res = fopen(envstr, "rb");
                if (res == NULL) {
                        warning("WARNING: GPSBabel-inifile, defined in environment, NOT found!\n");
                        return NULL;
@@ -121,24 +121,15 @@ static void
 inifile_load_file(FILE *fin, inifile_t *inifile, const char *myname)
 {
        char *buf;
-       size_t bufsize = START_BUFSIZE;
        inifile_section_t *sec = NULL;
+       textfile_t *tin;
 
-       buf = xmalloc(bufsize);
+       tin = textfile_init(fin);
        
-       while ((fgets(buf, bufsize, fin)))
+       while ((buf = textfile_read(tin)))
        {
-               char *cin;
-       
-               while (strchr(buf, '\n') == NULL)
-               {
-                       buf = xrealloc(buf, bufsize + DELTA_BUFSIZE);
-                       cin = fgets(buf + bufsize - 1, DELTA_BUFSIZE + 1, fin);
-                       bufsize+=DELTA_BUFSIZE;
-                       if (cin == NULL) break;
-               }
+               char *cin = lrtrim(buf);
                
-               cin = lrtrim(buf);
                if (*cin == '\0') continue;                     /* skip empty lines */
                if ((*cin == '#') || (*cin == ';')) continue;   /* skip comments */
                
@@ -192,7 +183,7 @@ inifile_load_file(FILE *fin, inifile_t *inifile, const char *myname)
                                entry->val = xstrdup("");
                }
        }
-       xfree(buf);
+       textfile_done(tin);
 }
 
 static char *
@@ -243,7 +234,7 @@ inifile_init(const char *filename, const char *myname)
                fin = open_gpsbabel_inifile();
                if (fin == NULL) return NULL;
        }
-       else fin = xfopen(filename, "r", myname);
+       else fin = xfopen(filename, "rb", myname);
        
        result = xcalloc(1, sizeof(*result));
        QUEUE_INIT(&result->secs);
index ded3c2c5b24139576baab0096c0a91c38dba72fd..ad7cf6068c366c142c1d544fb7a05fc2c8f04ae9 100644 (file)
@@ -54,7 +54,7 @@ arglist_t netstumbler_args[] = {
 static void
 rd_init(const char *fname)
 {
-       file_in = xfopen(fname, "r", MYNAME);
+       file_in = xfopen(fname, "rb", MYNAME);
        macstumbler = 0;
 }
 
@@ -67,7 +67,7 @@ rd_deinit(void)
 static void
 data_read(void)
 {
-       char ibuf[512];
+       char *ibuf;
        char ssid[2 + 32 + 2 + 1];                      /* "( " + SSID + " )" + null */
        char mac[2 + 17 + 2 + 1];                       /* "( " + MAC + " )" + null */
        char desc[sizeof ssid - 1 + 15 + 1];    /* room for channel/speed */
@@ -78,13 +78,16 @@ data_read(void)
        long flags = 0;
        int speed = 0, channel = 0;
        struct tm tm;
-
+       textfile_t *tin;
+       
+       tin = textfile_init(file_in);
        memset(&tm, 0, sizeof(tm));
 
-       for(; fgets(ibuf, sizeof(ibuf), file_in);) {
+       while ((ibuf = textfile_read(tin))) {
                char *field;
                int field_num, len, i, stealth = 0;
                
+               ibuf = lrtrim(ibuf);
         /* A sharp in column zero might be a comment.  Or it might be
          * something useful, like the date.
         */
@@ -221,7 +224,7 @@ data_read(void)
 
                waypt_add(wpt_tmp);
        }
-
+       textfile_done(tin);
        fix_netstumbler_dupes();
 }
 
diff --git a/nmea.c b/nmea.c
index 51573143ac090fac221cfc496e1713e5eff2fa89..f2b6f6fcb66e2c4851efebaf9c035d2bbb9b795e 100644 (file)
--- a/nmea.c
+++ b/nmea.c
@@ -200,7 +200,7 @@ nmea_rd_init(const char *fname)
 {
        curr_waypt = NULL;
        last_waypt = NULL;
-       file_in = xfopen(fname, "r", MYNAME);
+       file_in = xfopen(fname, "rb", MYNAME);
 }
 
 static  void
@@ -708,9 +708,10 @@ nmea_parse_one_line(char *ibuf)
 static void
 nmea_read(void)
 {
-       char ibuf[1024];
+       char *ibuf;
        char *ck;
        double lt = -1;
+       textfile_t *tin;
 
        posn_type = gp_unknown;
        trk_head = NULL;
@@ -730,8 +731,9 @@ nmea_read(void)
        }
 
        curr_waypt = NULL; 
+       tin = textfile_init(file_in);
 
-       while (fgets(ibuf, sizeof(ibuf), file_in)) {
+       while ((ibuf = textfile_read(tin))) {
                nmea_parse_one_line(ibuf);
                if (lt < last_read_time && curr_waypt && trk_head) {
                        if (curr_waypt != last_waypt) {
@@ -744,6 +746,8 @@ nmea_read(void)
 
        /* try to complete date-less trackpoints */
        nmea_fix_timestamps(trk_head);
+       
+       textfile_done(tin);
 }
 
 
diff --git a/nmn4.c b/nmn4.c
index cd5ec473eacb14460c12075a86f3b0ce508a59e1..fea273a5521fb4c8e9c060c09929d1ad9f7888dd 100644 (file)
--- a/nmn4.c
+++ b/nmn4.c
@@ -97,20 +97,6 @@ nmn4_concat(char *arg0, ...)
        return res;
 }
 
-static char *
-nmn4_read_line(char *buff, size_t buffsize, FILE *fin)
-{
-       char *res;
-       
-       while ((res = fgets(buff, buffsize, fin)))
-       {
-               res = lrtrim(res);
-               if (*res == '\0') continue;
-               return res;
-       }
-       return NULL;
-}
-
 static void
 nmn4_check_line(char *line)
 {
@@ -128,19 +114,24 @@ nmn4_check_line(char *line)
 static void
 nmn4_read_data(void)
 {
-       char buff[1024];
+       char *buff;
        char *str, *c;
        int column;
 
        char *zip1, *zip2, *city, *street, *number;     
        route_head *route;
        waypoint *wpt;
+       textfile_t *tin;
        
        route = route_head_alloc();
        route_add_head(route);
        
-       while ((str = nmn4_read_line(buff, sizeof(buff), fin)))
+       tin = textfile_init(fin);
+       while ((buff = textfile_read(tin)))
        {
+               str = buff = lrtrim(buff);
+               if (*buff == '\0') continue;
+               
                nmn4_check_line(buff);
 
                /* for a quiet compiler */
@@ -235,6 +226,7 @@ nmn4_read_data(void)
                }
                route_add_wpt(route, wpt);
        }
+       textfile_done(tin);
 }
 
 static void 
@@ -299,7 +291,7 @@ nmn4_write_data(void)
 static void
 nmn4_rd_init(const char *fname)
 {
-       fin = xfopen(fname, "r", MYNAME);
+       fin = xfopen(fname, "rb", MYNAME);
        fin_name = xstrdup(fname);
 }
 
diff --git a/ozi.c b/ozi.c
index 985b34250d0430c52acf467d81f4349418b3ae92..e90c50927f2ae38f2b1e4bc2443159ec0f8ff062 100644 (file)
--- a/ozi.c
+++ b/ozi.c
@@ -310,7 +310,7 @@ ozi_route_pr()
 static void
 rd_init(const char *fname)
 {
-    file_in = xfopen(fname, "r", MYNAME);
+    file_in = xfopen(fname, "rb", MYNAME);
 
     mkshort_handle = mkshort_new_handle();
 }
@@ -577,16 +577,17 @@ ozi_parse_routeheader(int field, char *str, waypoint * wpt_tmp)
 static void
 data_read(void)
 {
-    char buff[1024];
+    char *buff;
     char *s;
     waypoint *wpt_tmp;
     int i;
     int linecount = 0;
+    textfile_t *tin;
+    
+    tin = textfile_init(file_in);
 
-    do {
+    while ((buff = textfile_read(tin))) {
         linecount++;
-        memset(buff, '\0', sizeof(buff));
-        fgets(buff, sizeof(buff), file_in);
 
         /* 
          * this is particularly nasty.  use the first line of the file
@@ -669,7 +670,8 @@ data_read(void)
             /* empty line */
         }
 
-    } while (!feof(file_in));
+    }
+    textfile_done(tin);
 }
 
 static void
diff --git a/pcx.c b/pcx.c
index 72100e111dd5462b7e0133861b94a6d757626c7f..2d6b5764d6994aa6d85cba17e94699ca68540672 100644 (file)
--- a/pcx.c
+++ b/pcx.c
@@ -48,7 +48,7 @@ arglist_t pcx_args[] = {
 static void
 rd_init(const char *fname)
 {
-       file_in = xfopen(fname, "r", MYNAME);
+       file_in = xfopen(fname, "rb", MYNAME);
 }
 
 static void
@@ -85,16 +85,18 @@ data_read(void)
        char time[9];
        char month[4];
        waypoint *wpt_tmp;
-       char buff[122];
+       char *buff;
        struct tm tm;
        route_head *track = NULL;
        route_head *route = NULL;
        int n; 
        char lathemi, lonhemi;
+       textfile_t *tin;
 
        read_as_degrees  = 0;
+       tin = textfile_init(file_in);
 
-       for(;fgets(buff, sizeof(buff), file_in);) 
+       while ((buff = textfile_read(tin)))
        {
                char *ibuf = lrtrim(buff);
                char *cp;
@@ -215,6 +217,7 @@ data_read(void)
                        ;
                }
        }
+       textfile_done(tin);
 }
 
 static void
index 7b0eeacd546160866084bc1189fd510df22caae3..462c14c1192a936d38578b30d1c8be4becb8dac5 100644 (file)
--- a/polygon.c
+++ b/polygon.c
@@ -195,17 +195,16 @@ polygon_process(void)
        int fileline = 0;
        int first = 1;
        int last = 0;
+       char *line;
+       textfile_t *tin;
 
-       FILE *polyfile = xfopen( polyfileopt, "r", MYNAME );
+       tin = textfile_open_read(polyfileopt, MYNAME );
        
         olat = olon = lat1 = lon1 = lat2 = lon2 = BADVAL;
-       while ( !feof(polyfile)) {
-           char line[200];
+       while ((line = textfile_read(tin))) {
            char *pound = NULL;
            int argsfound = 0;
            
-           fgets( line, sizeof(line), polyfile );
-          
            fileline++;
            
            pound = strchr( line, '#' );
@@ -268,9 +267,7 @@ polygon_process(void)
                lon1 = lon2;
            }
        }
-           
-       fclose(polyfile);
-
+       textfile_done(tin);
 
        QUEUE_FOR_EACH(&waypt_head, elem, tmp) {
                waypoint *wp = (waypoint *) elem;
index 7dc1fda14f34c5fb5e9ae17e319fb36ebdda5105..4a765f0a74914f280cbf7332e86ae561f637309e 100644 (file)
--- a/stmwpp.c
+++ b/stmwpp.c
@@ -56,7 +56,7 @@ arglist_t stmwpp_args[] =
 static void
 stmwpp_rd_init(const char *fname)
 {
-       fin = xfopen(fname, "r", MYNAME);
+       fin = xfopen(fname, "rb", MYNAME);
        track = NULL;
        route = NULL;
        wpt = NULL;
@@ -71,15 +71,19 @@ stmwpp_rd_deinit(void)
 static void
 stmwpp_data_read(void)
 {
-       char buff[1024];
+       char *buff;
+       textfile_t *tin;
+       
+       tin = textfile_init(fin);
        
        what = STM_NOTHING;
-       fgets(buff, sizeof(buff), fin);
+       buff = textfile_read(tin);
+       buff = (buff == NULL) ? "" : buff;
        
        if (strncmp(buff, "Datum,WGS 84,WGS 84,", 20) != 0)
                fatal(MYNAME ": Invalid GPS datum or not \"WaypointPlus\"\" file!\n");
        
-       while (fgets(buff, sizeof(buff), fin) != NULL)
+       while ((buff = textfile_read(tin)))
        {
                char *c;
                int column = -1;
@@ -177,6 +181,7 @@ stmwpp_data_read(void)
                        wpt = NULL;
                }
        }
+       textfile_done(tin);
 }
 
 static void
diff --git a/textfile.c b/textfile.c
new file mode 100644 (file)
index 0000000..a500c9f
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+    Utilities for reading textfiles.
+
+    Copyright (C) 2006 Olaf Klein 
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+#include "defs.h"
+
+textfile_t *
+textfile_init(const FILE *file_in)
+{
+       textfile_t *res;
+       
+       res = xcalloc(1, sizeof(*res));
+       
+       res->file_in = (FILE *)file_in;
+       res->buf_pos = res->buf_end = res->buf;
+       res->line = xstrdup("");
+       
+       return res;
+}
+
+textfile_t *
+textfile_open_read(const char *filename, const char *module)
+{
+       textfile_t *tf;
+       
+       tf = textfile_init(xfopen(filename, "rb", module));
+       tf->tfclose = 1;
+       return tf;
+}
+
+int
+textfile_getc(textfile_t *tf)
+{
+       int res;
+       
+       if (tf->buf_pos == tf->buf_end) {
+               int bytes;
+               
+               tf->buf_pos = tf->buf_end = tf->buf;
+               bytes = fread(tf->buf, 1, sizeof(tf->buf), tf->file_in);
+               tf->buf_end += bytes;
+               
+               if (bytes == 0) {
+                       *tf->buf_pos = 0x1a;
+                       tf->buf_end++;
+                       return EOF;
+               }
+       }
+       res = *tf->buf_pos;
+       if (res == 0x1a) return EOF;
+       else {
+               tf->buf_pos++;
+               return res;
+       }
+}
+
+unsigned char
+textfile_eof(textfile_t *tf)
+{
+       int ch = textfile_getc(tf);
+       
+       if (ch == EOF) return 1;
+       else {
+               tf->buf_pos--;
+               return 0;
+       }
+}
+
+char *textfile_read(textfile_t *tf)
+{
+       int len = 0;
+       char *res = tf->line;
+       
+       tf->line_no++;
+       
+       while (1) {
+               int c = textfile_getc(tf);
+               
+               if ((c == EOF) || (c == 0x1a)) {
+                       if (len == 0) return NULL;
+                       else break;
+               }
+               else if (c == '\r') {
+                       c = textfile_getc(tf);
+                       if (c != '\n') tf->buf_pos--;
+                       break;
+               }
+               else if (c == '\n') {
+                       break;
+               }
+               if (len == tf->line_size) {
+                       tf->line_size+=128;
+                       res = tf->line = xrealloc(tf->line, tf->line_size + 1);
+               }
+               res[len] = c;
+               len++;
+       }
+       res[len] = '\0';
+       return res;
+}
+
+void
+textfile_done(textfile_t *tf)
+{
+       xfree(tf->line);
+       if (tf->tfclose) fclose(tf->file_in);
+       xfree(tf);
+}
diff --git a/tiger.c b/tiger.c
index ab0953d820dae98493d149f3de611d6e5d3d5439..d97511e6dfd0616caf1a7ef6e74d947df88c3be9 100644 (file)
--- a/tiger.c
+++ b/tiger.c
@@ -99,7 +99,7 @@ arglist_t tiger_args[] = {
 static void
 rd_init(const char *fname)
 {
-       file_in = xfopen(fname, "r", MYNAME);
+       file_in = xfopen(fname, "rb", MYNAME);
        mkshort_handle = mkshort_new_handle();
 }
 
@@ -129,10 +129,13 @@ data_read(void)
        double lat,lon;
        char desc[100];
        char icon[100];
-       char ibuf[1024];
+       char *ibuf;
        waypoint *wpt_tmp;
+       textfile_t *tin;
 
-       while (fgets(ibuf, sizeof(ibuf), file_in)) {
+       tin = textfile_init(file_in);
+       
+       while ((ibuf = textfile_read(tin))) {
                if( sscanf(ibuf, "%lf,%lf:%100[^:]:%100[^\n]", 
                                &lon, &lat, icon, desc)) {
                        wpt_tmp = waypt_new();
@@ -145,6 +148,7 @@ data_read(void)
                        waypt_add(wpt_tmp);
                }
        }
+       textfile_done(tin);
 }
 
 static void
diff --git a/tmpro.c b/tmpro.c
index 73c23e7380528ada3c2b9b670c0cdeb1cf00ada8..a0b3018db294926c003928663d84f3fb06f4dfcf 100644 (file)
--- a/tmpro.c
+++ b/tmpro.c
@@ -45,7 +45,7 @@ static short_handle mkshort_handle;
 static void 
 rd_init(const char *fname)
 {
-    file_in = xfopen(fname, "r", MYNAME);
+    file_in = xfopen(fname, "rb", MYNAME);
 }
 
 static void 
@@ -69,17 +69,18 @@ wr_deinit(void)
 static void 
 data_read(void)
 {
-    char buff[1024];
+    char *buff;
     char *s;
     char *holder;
     waypoint *wpt_tmp;
     int i;
     int linecount = 0;
-
-    do {
+    textfile_t *tin;
+    
+    tin = textfile_init(file_in);
+    
+    while ((buff = textfile_read(tin))) {
         linecount++;
-       memset(&buff, '\0', sizeof(buff));
-       fgets(buff, sizeof(buff), file_in);
 
        /* skip the line if it contains "sHyperLink" as it is a header (I hope :) */
        if ((strlen(buff)) && (strstr(buff, "sHyperLink") == NULL)) {
@@ -170,7 +171,8 @@ data_read(void)
             /* empty line */
        }
 
-    } while (!feof(file_in));
+    }
+    textfile_done(tin);
 }
 
 static void 
index 1deddd8e31875dc9ece3081537976282ee3ffdde..a5de55a4d33935177bf4dda80ccb1217408abaa9 100644 (file)
--- a/unicsv.c
+++ b/unicsv.c
@@ -25,6 +25,7 @@
 #define MYNAME "unicsv"
 
 static FILE *fin;
+static textfile_t *tin;
 
 /* This structure must contain only ints.  Firstval must be first.
  * This is block initialized.
@@ -55,11 +56,11 @@ arglist_t unicsv_args[] = {
 
 /* fread_buff: returns only left and right trimmed non-empty lines or NULL */
 static char *
-fread_buff(char *buff, const size_t buff_size, FILE *fin)
+fread_buff(textfile_t *tin)
 {
        char *result;
        
-       while ((result = fgets(buff, buff_size, fin)))
+       while ((result = textfile_read(tin)))
        {
                result = lrtrim(result);
                if (*result != '\0') break;
@@ -139,13 +140,14 @@ unicsv_fondle_header(char *ibuf)
 static void
 unicsv_rd_init(const char *fname)
 {
-       char ibuf[1024];
+       char *c;
        unicsv_altscale = 1.0;
 
-       fin = xfopen(fname, "r", MYNAME);
+       fin = xfopen(fname, "rb", MYNAME);
+       tin = textfile_init(fin);
 
-       if (NULL != fread_buff(ibuf, sizeof(ibuf), fin))
-               unicsv_fondle_header(ibuf);
+       if ((c = textfile_read(tin)))
+               unicsv_fondle_header(c);
        else
                unicsv_fieldsep = NULL;
 }
@@ -153,8 +155,8 @@ unicsv_rd_init(const char *fname)
 static void
 unicsv_rd_deinit(void)
 {
+       textfile_done(tin);
        fclose(fin);
-       fin = NULL;
 }
 
 static void
@@ -214,12 +216,14 @@ unicsv_parse_one_line(char *ibuf)
 static void 
 unicsv_rd(void)
 {
-       char buff[1024];
+       char *buff;
 
        if (unicsv_fieldsep == NULL) return;
        
-       while (fread_buff(buff, sizeof(buff), fin)) {
-               unicsv_parse_one_line(buff);
+       while ((buff = textfile_read(tin))) {
+               buff = lrtrim(buff);
+               if (*buff)
+                       unicsv_parse_one_line(buff);
        }
 }
 
diff --git a/xcsv.c b/xcsv.c
index 1b6d114a24c2e730927d95e7e131c30e81894900..64a4ff34eaeafd1b9a75fcc65d8832de1b5ebf09 100644 (file)
--- a/xcsv.c
+++ b/xcsv.c
@@ -440,17 +440,17 @@ xcsv_parse_style_buff(const char *sbuff)
 static void
 xcsv_read_style(const char *fname)
 {
-    char sbuff[8192];
+    char *sbuff;
     FILE *fp;
+    textfile_t *tin;
 
     xcsv_file_init();
 
-    fp = xfopen(fname, "r", MYNAME);
+    fp = xfopen(fname, "rb", MYNAME);
+    tin = textfile_init(fp);
 
-    do {
-        memset(sbuff, '\0', sizeof(sbuff));
-        fgets(sbuff, sizeof(sbuff), fp);
-        rtrim(sbuff);
+    while ((sbuff = textfile_read(tin))) {
+        sbuff = lrtrim(sbuff);
        xcsv_parse_style_line(sbuff);
     } while (!feof(fp));
 
@@ -461,7 +461,7 @@ xcsv_read_style(const char *fname)
         xcsv_file.ofield = &xcsv_file.ifield;
         xcsv_file.ofield_ct = xcsv_file.ifield_ct;
     }
-
+    textfile_done(tin);
     fclose(fp);
 }